<?php
	require_once 'libs/errors.php';

	class validations {
		private $route, $field, $value, $min, $max;


		function __construct(string $route) {
			$this -> route = $route;
		}


		private function message_add($message) {
			array_push($_SESSION['messages'], $message);
		}


		// Muestra todos los mensajes de validación sobre '$route'
		// y termina la ejecución de todos los scripts.
		private function messages() {
			if (!empty($_SESSION['messages'])) {
				header('Location: ' . $this -> route);

				exit;
			}
		}


		// Valida la longitud de un campo de un formulario.
		private function validate_length() {
			$lenght = strlen($this -> value);
			
			if (!($lenght >= $this -> min && $lenght <= $this -> max))
				errors("El campo '" . $this -> field . "' no cumple los límites establecidos");
		}


		// Valida si un campo es un número entero.
		private function validate_integer() {
			$options = array('options' => array(
				'min_range' => $this -> min,
				'max_range' => $this -> max
			));

			if (!filter_var($this -> value, FILTER_VALIDATE_INT, $options))
				errors("El campo '" . $this -> field . "' no cumple los límites establecidos");
		}


		// Valida si un campo es una dirección de correo electrónico,
		// y el dominio sea de la Universidad de Guanajuato.
		private function validate_email() {
			$email = $this -> value;

			if (filter_var($email, FILTER_VALIDATE_EMAIL))
				if (!str_ends_with($email, '@ugto.mx'))
					$this -> message_add('Registrate con tu dirección de correo electrónico institucional de la Universidad de Guanajuato');
			else
				$this -> message_add("El campo '" . $this -> field . "' contiene una dirección no válida");
		}


		// Valida si dos datos son iguales.
		private function validate_equal($foo) {
			if ($this -> value !== $foo)
				$this -> message_add("No coindice el campo '" . $this -> field . "'");
		}


		// Valida si un campo contiene espacios.
		private function validate_spaces() {
			if (!ctype_graph($this -> value))
				$this -> message_add("El campo '" . $this -> field . "' contiene espacios");
		}


		// Valida y selecciona los campos de un formulario;
		// retorna un array asociativo con datos validados.
		public function validate_form(array $form, array $options) {
			$data = array(); // Almacena datos seleccionados y validados.

			foreach ($options as $key) {
				if (!is_array($options))
					errors('Las opciones de validación no son un array');

				if (!(is_string($key[0]) && is_int($key['min']) && is_int($key['max'])))
					errors('No se encontró el nombre, y la longitud mínima y máxima del campo');

				$this -> field = $key[0];
				$this -> min   = $key['min'];
				$this -> max   = $key['max'];

				// Campo obligatorio (default: false).
				$exist = empty($key['exist']) ? false : true;

				// Tipo de dato (default: strig).
				$type  = empty($key['type']) ? 'string' : $key['type'];

				// Valida si un campo es obligatorio u opcional.
				if ($exist)
					if (empty($form[$this -> field]))
						errors("El campo '" . $this -> field . "' es obligatorio");
				else
					if (empty($form[$this -> field]))
						continue; 

				// Limipia espacios sobrantes, y espacios de principio y fin.
				$this -> value = trim(preg_replace('/\s+/', ' ', $form[$this -> field]));

				switch ($type) {
					case 'string':
						$this -> validate_length();
	
						if (!empty($key['is_email']))
							$this -> validate_email();

						break;
					case 'integer':
						$this -> validate_integer();

						break;
					default:
						errors("Tipo de dato '" . $type . "' inválido");
				}

				if (!empty($key['equal']))
					$this -> validate_equal($key['equal']);

				if (!empty($key['not_spaces']))
					$this -> validate_spaces();

				$data[$this -> field] = $this -> value;
			}

			$this -> messages();

			return $data;
		}
	}